package net.homeip.jcperera.nu.security.user;

import java.security.Principal;

import javax.inject.Named;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Embedded;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Table;
import javax.persistence.Transient;

import net.homeip.jcperera.nu.model.entity.PersistentEntity;
import net.homeip.jcperera.nu.security.credential.Credential;
import net.homeip.jcperera.nu.security.credential.IdentificationTag;
import net.homeip.jcperera.nu.security.credential.Password;

/**
 * User, referring to a User of the System, one of the core Entities
 * 
 * @name User class
 * @author julio.c.perera@gmail.com
 * @application nu
 * @since 0.1.0.0
 */

@Named(User.componentName)
@Table(name = User.tableName)
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorValue(value = User.tableName)
public class User extends PersistentEntity implements Principal
{
    // Required to implement Serializable interface
    private static final long  serialVersionUID = 29570145257953530L;

    // CoreBase properties, for easy use from other components, as well as logging
    public static final int    runtimeLevel     = 2;
    public static final String moduleName       = "security";
    public static final String componentName    = "nu_security_user";

    // All persistent entities should specify a table name
    public static final String tableName        = "USER";

    @Embedded
    private Credential         credential       = new Password();

    @Embedded
    private IdentificationTag  idTag            = new Login();

    // A default constructor is a must for this framework!!
    public User()
    {
        super();
    }

    /**
     * @return the idTag
     */
    public IdentificationTag getIdTag()
    {
        return this.idTag;
    }

    /**
     * @param idTag
     *            the idTag to set
     */
    public void setIdTag(IdentificationTag idTag)
    {
        this.idTag = idTag;
    }

    /**
     * @return the credential
     */

    public Credential getCredential()
    {
        return this.credential;
    }

    /**
     * User Credential (for Authentication)
     * 
     * @param newVal
     */
    public void setCredential(Credential newVal)
    {
        this.credential = newVal;
    }

    /**
     * Returns the name (same as String representation of the IdTag) of this User
     */
    @Transient
    public String getName()
    {
        return this.idTag.toString();
    }

    /**
     * Returns a string representation of the object. In general, the <code>toString</code> method returns a string that
     * "textually represents" this object. The result should be a concise but informative representation that is easy
     * for a person to read. It is recommended that all subclasses override this method.
     * <p>
     * The <code>toString</code> method for class <code>Object</code> returns a string consisting of the name of the
     * class of which the object is an instance, the at-sign character `<code>@</code>', and the unsigned hexadecimal
     * representation of the hash code of the object. In other words, this method returns a string equal to the value
     * of: <blockquote>
     * 
     * <pre>
     * getClass().getName() + '@' + Integer.toHexString(hashCode())
     * </pre>
     * 
     * </blockquote>
     * 
     * @return a string representation of the object.
     */
    @Override
    public String toString()
    {
        return "";
    }

    /**
     * Verify the credential against another credential, returning true if these match or false otherwise
     * 
     * @param verificationCredential
     */
    public boolean verifyCredential(Credential verificationCredential)
    {
        return this.credential.verify(verificationCredential);
    }

    /**
     * Compares this principal to the specified object. Returns true if the object passed in matches the principal
     * represented by the implementation of this interface.
     * 
     * @return true if the principal passed in is the same as that encapsulated by this principal, and false otherwise.
     * @param another
     *            principal to compare with.
     */
    @Override
    public boolean equals(Object another)
    {
        return false;
    }

    /**
     * Returns a hashcode for this principal.
     * 
     * @return a hashcode for this principal.
     */
    @Override
    public int hashCode()
    {
        return 0;
    }
}